#include <vmtypes.h>
#include <pio.h>
#include <logging.h>
#include "headset_usb.h"
#include "headset_test.h"
#include "ui.h"
#include "zy_touch_7211e.h"
#include "zy_i2c.h"
#include "adi1787.h"


#ifdef ENABLE_TOUCH_FOR_IQS7211E
#define IQS7211E_ADDR               0x56
bool iqs7211e_inited = FALSE;

static bool IQS7211E_Init(void)
{
    uint8 buffer[40];

    /* Change the ALP ATI Compensation */
    /* Memory Map Position 0x1F - 0x20 */
    buffer[0] = ALP_COMPENSATION_A_0;
    buffer[1] = ALP_COMPENSATION_A_1;
    buffer[2] = ALP_COMPENSATION_B_0;
    buffer[3] = ALP_COMPENSATION_B_1;

    i2c_write_byte_nbit(IQS7211E_ADDR, 0x1F, &buffer[0], 4);

    /* Change the ATI Settings */
    /* Memory Map Position 0x21 - 0x27 */
    buffer[0] = TP_ATI_MULTIPLIERS_DIVIDERS_0;
    buffer[1] = TP_ATI_MULTIPLIERS_DIVIDERS_1;
    buffer[2] = TP_COMPENSATION_DIV;
    buffer[3] = TP_REF_DRIFT_LIMIT;
    buffer[4] = TP_ATI_TARGET_0;
    buffer[5] = TP_ATI_TARGET_1;
    buffer[6] = TP_MIN_COUNT_REATI_0;
    buffer[7] = TP_MIN_COUNT_REATI_1;
    buffer[8] = ALP_ATI_MULTIPLIERS_DIVIDERS_0;
    buffer[9] = ALP_ATI_MULTIPLIERS_DIVIDERS_1;
    buffer[10] = ALP_COMPENSATION_DIV;
    buffer[11] = ALP_LTA_DRIFT_LIMIT;
    buffer[12] = ALP_ATI_TARGET_0;
    buffer[13] = ALP_ATI_TARGET_1;

    i2c_write_byte_nbit(IQS7211E_ADDR, 0x21, &buffer[0], 14);

    /* Change the Report Rates and Timing */
    /* Memory Map Position 0x28 - 0x32 */
    buffer[0] = ACTIVE_MODE_REPORT_RATE_0;
    buffer[1] = ACTIVE_MODE_REPORT_RATE_1;
    buffer[2] = IDLE_TOUCH_MODE_REPORT_RATE_0;
    buffer[3] = IDLE_TOUCH_MODE_REPORT_RATE_1;
    buffer[4] = IDLE_MODE_REPORT_RATE_0;
    buffer[5] = IDLE_MODE_REPORT_RATE_1;
    buffer[6] = LP1_MODE_REPORT_RATE_0;
    buffer[7] = LP1_MODE_REPORT_RATE_1;
    buffer[8] = LP2_MODE_REPORT_RATE_0;
    buffer[9] = LP2_MODE_REPORT_RATE_1;
    buffer[10] = ACTIVE_MODE_TIMEOUT_0;
    buffer[11] = ACTIVE_MODE_TIMEOUT_1;
    buffer[12] = IDLE_TOUCH_MODE_TIMEOUT_0;
    buffer[13] = IDLE_TOUCH_MODE_TIMEOUT_1;
    buffer[14] = IDLE_MODE_TIMEOUT_0;
    buffer[15] = IDLE_MODE_TIMEOUT_1;
    buffer[16] = LP1_MODE_TIMEOUT_0;
    buffer[17] = LP1_MODE_TIMEOUT_1;
    buffer[18] = REATI_RETRY_TIME;
    buffer[19] = REF_UPDATE_TIME;
    buffer[20] = I2C_TIMEOUT_0;
    buffer[21] = I2C_TIMEOUT_1;

    i2c_write_byte_nbit(IQS7211E_ADDR, 0x28, &buffer[0], 22);

    /* Change the ALP Settings */
    /* Memory Map Position 0x36 - 0x40 */
    buffer[0] = ALP_SETUP_0;
    buffer[1] = ALP_SETUP_1;
    buffer[2] = ALP_TX_ENABLE_0;
    buffer[3] = ALP_TX_ENABLE_1;
    buffer[4] = TRACKPAD_TOUCH_SET_THRESHOLD;
    buffer[5] = TRACKPAD_TOUCH_CLEAR_THRESHOLD;
    buffer[6] = ALP_THRESHOLD_0;
    buffer[7] = ALP_THRESHOLD_1;
    buffer[8] = ALP_SET_DEBOUNCE;
    buffer[9] = ALP_CLEAR_DEBOUNCE;
    buffer[10] = ALP_COUNT_BETA_LP1;
    buffer[11] = ALP_LTA_BETA_LP1;
    buffer[12] = ALP_COUNT_BETA_LP2;
    buffer[13] = ALP_LTA_BETA_LP2;
    buffer[14] = TP_CONVERSION_FREQUENCY_UP_PASS_LENGTH;
    buffer[15] = TP_CONVERSION_FREQUENCY_FRACTION_VALUE;
    buffer[16] = ALP_CONVERSION_FREQUENCY_UP_PASS_LENGTH;
    buffer[17] = ALP_CONVERSION_FREQUENCY_FRACTION_VALUE;
    buffer[18] = TRACKPAD_HARDWARE_SETTINGS_0;
    buffer[19] = TRACKPAD_HARDWARE_SETTINGS_1;
    buffer[20] = ALP_HARDWARE_SETTINGS_0;
    buffer[21] = ALP_HARDWARE_SETTINGS_1;

    i2c_write_byte_nbit(IQS7211E_ADDR, 0x36, &buffer[0], 22);

    /* Change the Trackpad Settings */
    /* Memory Map Position 0x41 - 0x4A */
    buffer[0] = TRACKPAD_SETTINGS_0_0;
    buffer[1] = TRACKPAD_SETTINGS_0_1;
    buffer[2] = TRACKPAD_SETTINGS_1_0;
    buffer[3] = TRACKPAD_SETTINGS_1_1;
    buffer[4] = X_RESOLUTION_0;
    buffer[5] = X_RESOLUTION_1;
    buffer[6] = Y_RESOLUTION_0;
    buffer[7] = Y_RESOLUTION_1;
    buffer[8] = XY_DYNAMIC_FILTER_BOTTOM_SPEED_0;
    buffer[9] = XY_DYNAMIC_FILTER_BOTTOM_SPEED_1;
    buffer[10] = XY_DYNAMIC_FILTER_TOP_SPEED_0;
    buffer[11] = XY_DYNAMIC_FILTER_TOP_SPEED_1;
    buffer[12] = XY_DYNAMIC_FILTER_BOTTOM_BETA;
    buffer[13] = XY_DYNAMIC_FILTER_STATIC_FILTER_BETA;
    buffer[14] = STATIONARY_TOUCH_MOV_THRESHOLD;
    buffer[15] = FINGER_SPLIT_FACTOR;
    buffer[16] = X_TRIM_VALUE;
    buffer[17] = Y_TRIM_VALUE;
    buffer[18] = MINOR_VERSION;
    buffer[19] = MAJOR_VERSION;

    i2c_write_byte_nbit(IQS7211E_ADDR, 0x41, &buffer[0], 20);

    /* Change the Gesture Settings */
    /* Memory Map Position 0x4B - 0x55 */
    buffer[0] = GESTURE_ENABLE_0;
    buffer[1] = GESTURE_ENABLE_1;
    buffer[2] = TAP_TOUCH_TIME_0;
    buffer[3] = TAP_TOUCH_TIME_1;
    buffer[4] = TAP_WAIT_TIME_0;
    buffer[5] = TAP_WAIT_TIME_1;
    buffer[6] = TAP_DISTANCE_0;
    buffer[7] = TAP_DISTANCE_1;
    buffer[8] = HOLD_TIME_0;
    buffer[9] = HOLD_TIME_1;
    buffer[10] = SWIPE_TIME_0;
    buffer[11] = SWIPE_TIME_1;
    buffer[12] = SWIPE_X_DISTANCE_0;
    buffer[13] = SWIPE_X_DISTANCE_1;
    buffer[14] = SWIPE_Y_DISTANCE_0;
    buffer[15] = SWIPE_Y_DISTANCE_1;
    buffer[16] = SWIPE_X_CONS_DIST_0;
    buffer[17] = SWIPE_X_CONS_DIST_1;
    buffer[18] = SWIPE_Y_CONS_DIST_0;
    buffer[19] = SWIPE_Y_CONS_DIST_1;
    buffer[20] = SWIPE_ANGLE;
    buffer[21] = PALM_THRESHOLD;

    i2c_write_byte_nbit(IQS7211E_ADDR, 0x4B, &buffer[0], 22);

    /* Change the RxTx Mapping */
    /* Memory Map Position 0x56 - 0x5C */
    buffer[0] = RX_TX_MAP_0;
    buffer[1] = RX_TX_MAP_1;
    buffer[2] = RX_TX_MAP_2;
    buffer[3] = RX_TX_MAP_3;
    buffer[4] = RX_TX_MAP_4;
    buffer[5] = RX_TX_MAP_5;
    buffer[6] = RX_TX_MAP_6;
    buffer[7] = RX_TX_MAP_7;
    buffer[8] = RX_TX_MAP_8;
    buffer[9] = RX_TX_MAP_9;
    buffer[10] = RX_TX_MAP_10;
    buffer[11] = RX_TX_MAP_11;
    buffer[12] = RX_TX_MAP_12;
    buffer[13] = RX_TX_MAP_FILLER;

    i2c_write_byte_nbit(IQS7211E_ADDR, 0x56, &buffer[0], 14);

    /* Change the Allocation of channels into cycles 0-9 */
    /* Memory Map Position 0x5D - 0x6B */
    buffer[0] = PLACEHOLDER_0;
    buffer[1] = CH_1_CYCLE_0;
    buffer[2] = CH_2_CYCLE_0;
    buffer[3] = PLACEHOLDER_1;
    buffer[4] = CH_1_CYCLE_1;
    buffer[5] = CH_2_CYCLE_1;
    buffer[6] = PLACEHOLDER_2;
    buffer[7] = CH_1_CYCLE_2;
    buffer[8] = CH_2_CYCLE_2;
    buffer[9] = PLACEHOLDER_3;
    buffer[10] = CH_1_CYCLE_3;
    buffer[11] = CH_2_CYCLE_3;
    buffer[12] = PLACEHOLDER_4;
    buffer[13] = CH_1_CYCLE_4;
    buffer[14] = CH_2_CYCLE_4;
    buffer[15] = PLACEHOLDER_5;
    buffer[16] = CH_1_CYCLE_5;
    buffer[17] = CH_2_CYCLE_5;
    buffer[18] = PLACEHOLDER_6;
    buffer[19] = CH_1_CYCLE_6;
    buffer[20] = CH_2_CYCLE_6;
    buffer[21] = PLACEHOLDER_7;
    buffer[22] = CH_1_CYCLE_7;
    buffer[23] = CH_2_CYCLE_7;
    buffer[24] = PLACEHOLDER_8;
    buffer[25] = CH_1_CYCLE_8;
    buffer[26] = CH_2_CYCLE_8;
    buffer[27] = PLACEHOLDER_9;
    buffer[28] = CH_1_CYCLE_9;
    buffer[29] = CH_2_CYCLE_9;

    i2c_write_byte_nbit(IQS7211E_ADDR, 0x5D, &buffer[0], 30);

    /* Change the Allocation of channels into cycles 10-19 */
    /* Memory Map Position 0x6C - 0x7C */
    buffer[0] = PLACEHOLDER_10;
    buffer[1] = CH_1_CYCLE_10;
    buffer[2] = CH_2_CYCLE_10;
    buffer[3] = PLACEHOLDER_11;
    buffer[4] = CH_1_CYCLE_11;
    buffer[5] = CH_2_CYCLE_11;
    buffer[6] = PLACEHOLDER_12;
    buffer[7] = CH_1_CYCLE_12;
    buffer[8] = CH_2_CYCLE_12;
    buffer[9] = PLACEHOLDER_13;
    buffer[10] = CH_1_CYCLE_13;
    buffer[11] = CH_2_CYCLE_13;
    buffer[12] = PLACEHOLDER_14;
    buffer[13] = CH_1_CYCLE_14;
    buffer[14] = CH_2_CYCLE_14;
    buffer[15] = PLACEHOLDER_15;
    buffer[16] = CH_1_CYCLE_15;
    buffer[17] = CH_2_CYCLE_15;
    buffer[18] = PLACEHOLDER_16;
    buffer[19] = CH_1_CYCLE_16;
    buffer[20] = CH_2_CYCLE_16;
    buffer[21] = PLACEHOLDER_17;
    buffer[22] = CH_1_CYCLE_17;
    buffer[23] = CH_2_CYCLE_17;
    buffer[24] = PLACEHOLDER_18;
    buffer[25] = CH_1_CYCLE_18;
    buffer[26] = CH_2_CYCLE_18;
    buffer[27] = PLACEHOLDER_19;
    buffer[28] = CH_1_CYCLE_19;
    buffer[29] = CH_2_CYCLE_19;
    buffer[30] = PLACEHOLDER_20;
    buffer[31] = CH_1_CYCLE_20;
    buffer[32] = CH_2_CYCLE_20;

    i2c_write_byte_nbit(IQS7211E_ADDR, 0x6C, &buffer[0], 33);

    /* Change the System Settings */
    /* Memory Map Position 0x33 - 0x35 */
    buffer[0] = SYSTEM_CONTROL_0 | 0x80 | 0x20; // Ack Reset, TP Re-ATI
    buffer[1] = SYSTEM_CONTROL_1;
    buffer[2] = CONFIG_SETTINGS0 | 0x40; // bit6 : 1 Write one or two bytes (any data) to the address 0xFF followed by a STOP to end comms
    buffer[3] = CONFIG_SETTINGS1 | 0x01; // 0x01 : Enable Event Mode
    buffer[4] = OTHER_SETTINGS_0;
    buffer[5] = OTHER_SETTINGS_1;

    bool ret = i2c_write_byte_nbit(IQS7211E_ADDR, 0x33, &buffer[0], 6);
    return ret;
}

void zy_touch_init(void)
{
    bool ret = IQS7211E_Init();
    if (ret)
    {
        DEBUG_LOG_INFO("IQS7211E_Init OK!");
        iqs7211e_inited = TRUE;
    }
    else
    {
        DEBUG_LOG_INFO("IQS7211E_Init Error!");
        iqs7211e_inited = FALSE;
    }
}

/*
//stop信号结束通信功能关闭
*/
static void IQS7211E_Stop_Bit_Disabled(void)
{
    uint8 buffer[1];

    buffer[0] = CONFIG_SETTINGS0 | 0x40; // bit6 : 1 Write one or two bytes (any data) to the address 0xFF followed by a STOP to end comms;
    i2c_write_byte_nbit(IQS7211E_ADDR, 0x34, &buffer[0], 1);
}

/*
//关闭通信窗口
*/
static void IQS7211E_Stop_I2C_Comm_Window(void)
{
    uint8 buffer[1];

    buffer[0] = CONFIG_SETTINGS0 & 0xBF; // bit6 : 1 Write one or two bytes (any data) to the address 0xFF followed by a STOP to end comms;
    i2c_write_byte_nbit(IQS7211E_ADDR, 0x34, &buffer[0], 1);
}

bool enter_monitor_by_touch = FALSE;
bool adjust_volume_by_touch = FALSE;
static void Process_IQS7211E_Events(void)
{
    uint8 System_Data_buffer[28];

    if (iqs7211e_inited)
    {
        IQS7211E_Stop_Bit_Disabled();

        i2c_read_byte(IQS7211E_ADDR, 0x0A, &System_Data_buffer[0], 20);
        if (System_Data_buffer[10] & 0x80)
        {
            IQS7211E_Init();
        }
        else
        {
            if (System_Data_buffer[10] & 0x20)
            { // ALP ATI Error
                DEBUG_LOG_INFO("IQS7211E_ALP_ATI_Error");
            }

            if (System_Data_buffer[10] & 0x08)
            { // ATI Error
                DEBUG_LOG_INFO("IQS7211E_ATI_Error");
            }
            else if (System_Data_buffer[10] & 0x10)
            { // ATI active
                DEBUG_LOG_INFO("IQS7211E_ATI_active");
            }
            else
            {
                // Single Tap
                if (System_Data_buffer[8] & 0x01)
                {
                    DEBUG_LOG_INFO("Single Tap");
                }

                // Double Tap
                else if (System_Data_buffer[8] & 0x02)
                {
                    DEBUG_LOG_INFO("Double Tap");
                    if (HeadsetUsb_IsAudioConnected())
                    {
                        Ui_InjectUiInput(ui_input_usb_toggle_play_pause);
                    }
                    else if (appTestIsHandsetHfpCall())
                    {
                        if (appTestIsHandsetHfpCallIncoming())
                        {
                            Ui_InjectUiInput(ui_input_voice_call_accept);
                        }
                        else
                        {
                            Ui_InjectUiInput(ui_input_voice_call_reject);
                        }
                    }
                    else if (appDeviceIsHandsetConnected())
                    {
                        Ui_InjectUiInput(ui_input_toggle_play_pause);
                    }
                }

                // Triple Tap
                else if (System_Data_buffer[8] & 0x04)
                {
                    DEBUG_LOG_INFO("Triple Tap");
                }

                // Press and Hold
                else if (System_Data_buffer[8] & 0x08)
                {
                    DEBUG_LOG_INFO("Press and Hold");
                }

                // Palm Gesture
                else if (System_Data_buffer[8] & 0x10)
                {
                    DEBUG_LOG_INFO("Palm Gesture");
                    if (enter_monitor_by_touch || adjust_volume_by_touch)
                    {
                        MessageCancelAll(AncGetTask(), EventMyIQS7211EPalmGestureStop);
                        MessageSendLater(AncGetTask(), EventMyIQS7211EPalmGestureStop, 0, 500);
                    }
                    else
                    {
                        if (anc_state == state_anc_on) /* 降噪开，跳转环境音 */
                        {
                            enter_monitor_by_touch = TRUE;
                            anc_adaptive_enabled_temp = anc_adaptive_enabled_temp | anc_adaptive_enabled;
                            if (anc_adaptive_enabled)
                            {
                                MessageSend(AncAdaptiveGetTask(), EventAncAdaptiveStop, 0);
                            }
                            ADI1787_Registers_write(i2c_addr_1787_8bit, ADI1787_BANK_CONTROL_REG, 1, BANK_B);
                        }
                        if (appDeviceIsHandsetConnected() || HeadsetUsb_IsAudioConnected())
                        {
                            adjust_volume_by_touch = TRUE;
                        }
                        if (enter_monitor_by_touch || adjust_volume_by_touch)
                        {
                            MessageCancelAll(AncGetTask(), EventMyIQS7211EPalmGestureStop);
                            MessageSendLater(AncGetTask(), EventMyIQS7211EPalmGestureStop, 0, 500);
                        }
                    }
                }

                // Swipe X+
                else if (System_Data_buffer[9] & 0x01)
                {
                    DEBUG_LOG_INFO("Swipe X+");
                    if (appDeviceIsHandsetConnected() || HeadsetUsb_IsAudioConnected())
                    {
                        Ui_InjectUiInput(ui_input_volume_up);
                    }
                }

                // Swipe X-
                else if (System_Data_buffer[9] & 0x02)
                {
                    DEBUG_LOG_INFO("Swipe X-");
                    if (appDeviceIsHandsetConnected() || HeadsetUsb_IsAudioConnected())
                    {
                        Ui_InjectUiInput(ui_input_volume_down);
                    }
                }

                // Swipe Y+
                else if (System_Data_buffer[9] & 0x04)
                {
                    DEBUG_LOG_INFO("Swipe Y+");
                    if (HeadsetUsb_IsAudioConnected())
                    {
                        Ui_InjectUiInput(ui_input_usb_backward);
                    }
                    else if (appDeviceIsHandsetConnected())
                    {
                        Ui_InjectUiInput(ui_input_av_backward);
                    }
                }

                // Swipe Y-
                else if (System_Data_buffer[9] & 0x08)
                {
                    DEBUG_LOG_INFO("Swipe Y-");
                    if (HeadsetUsb_IsAudioConnected())
                    {
                        Ui_InjectUiInput(ui_input_usb_forward);
                    }
                    else if (appDeviceIsHandsetConnected())
                    {
                        Ui_InjectUiInput(ui_input_av_forward);
                    }
                }

                // Swipe and Hold X+
                else if (System_Data_buffer[9] & 0x10)
                {
                    DEBUG_LOG_INFO("Swipe and Hold X+");
                }

                // Swipe and Hold X-
                else if (System_Data_buffer[9] & 0x20)
                {
                    DEBUG_LOG_INFO("Swipe and Hold X-");
                }

                // Swipe and Hold Y+
                else if (System_Data_buffer[9] & 0x40)
                {
                    DEBUG_LOG_INFO("Swipe and Hold Y+");
                }

                // Swipe and Hold Y-
                else if (System_Data_buffer[9] & 0x80)
                {
                    DEBUG_LOG_INFO("Swipe and Hold Y-");
                }
            }
        }

        IQS7211E_Stop_I2C_Comm_Window();

    }
}

void IQS7211E_Palm_Gesture_Stop(void)
{
    uint8 System_Data_buffer[28];
    bool palm_gesture_stop = TRUE;

    if (enter_monitor_by_touch || adjust_volume_by_touch)
    {
        IQS7211E_Stop_Bit_Disabled();
        i2c_read_byte(IQS7211E_ADDR, 0x0A, &System_Data_buffer[0], 20);
        if (System_Data_buffer[10] & 0x80)
        {
            IQS7211E_Init();
        }
        else if (System_Data_buffer[10] & 0x20)
        { // ALP ATI Error
            DEBUG_LOG_INFO("error 1");
        }
        else if (System_Data_buffer[10] & 0x08)
        { // ATI Error
            DEBUG_LOG_INFO("error 2");
        }
        else if (System_Data_buffer[10] & 0x10)
        { // ATI active
            DEBUG_LOG_INFO("error 3");
        }
        else
        {
            if (System_Data_buffer[8] & 0x10)
            {
                DEBUG_LOG_INFO("palm gesture");
                palm_gesture_stop = FALSE;
                MessageCancelAll(AncGetTask(), EventMyIQS7211EPalmGestureStop);
                MessageSendLater(AncGetTask(), EventMyIQS7211EPalmGestureStop, 0, 500);
            }
        }
        IQS7211E_Stop_I2C_Comm_Window();
    }
    else
    {
        DEBUG_LOG_INFO("error state");
    }
    
    if (palm_gesture_stop)
    {
         DEBUG_LOG_INFO("palm_gesture_stop");
        if (enter_monitor_by_touch)
        {
            enter_monitor_by_touch = FALSE;
            // if ((lState == deviceConnected) || (lState == deviceA2DPStreaming) || sinkUsbIsSpeakerActive())
            // {
            //     MessageSendLater(AncGetTask(), EventMyRestoreVolume, 0, 100);
            // }
            if (anc_adaptive_enabled_temp)
            {
                anc_adaptive_enabled_temp = FALSE;
                MessageSendLater(AncAdaptiveGetTask(), EventAncAdaptiveStart, 0, 5000);
            }
            ADI1787_Registers_write(i2c_addr_1787_8bit, ADI1787_BANK_CONTROL_REG, 1, BANK_A);
        }
        if (adjust_volume_by_touch)
        {
            adjust_volume_by_touch = FALSE;
            // if ((lState == deviceConnected) || (lState == deviceA2DPStreaming) || sinkUsbIsSpeakerActive())
            // {
            //     MessageSendLater(AncGetTask(), EventMyRestoreVolume, 0, 0);
            // }
        }   
    }
}

void zy_touch_interp_process(void)
{
#ifdef ENABLE_TOUCH_FOR_IQS7211E
    Process_IQS7211E_Events();
#endif
}
#endif
